package com.kgcx.dbutils.aspect;

import com.kgcx.common.aspect.utils.AspectUtils;
import com.kgcx.common.bean.RequestData;
import com.kgcx.common.bean.ReturnData;
import com.kgcx.common.client.organization.CityClient;
import com.kgcx.common.client.organization.pojo.City;
import com.kgcx.common.constant.Cons;
import com.kgcx.common.exception.BusinessException;
import com.kgcx.common.utils.CollectionUtils;
import com.kgcx.dbutils.annotation.service.CityValidator;
import feign.codec.DecodeException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;

/**
 * @author wuganglin
 * Created by Administrator on 2017/2/20.
 */
@Component
@Aspect
@SuppressWarnings("unchecked")
public class ServiceAspect {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private CityClient cityClient;

    @Pointcut("execution(public * com.kgcx.*.controller.*.*(..)) ")
    public void pointcut() {
    }

    //应用周围通知
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint call) {


        try {
            Signature signature = call.getSignature();
            /*if (!(signature instanceof MethodSignature)) {
                throw new IllegalArgumentException("该注解只能用于方法");
            }*/
            MethodSignature msig = (MethodSignature) signature;
            Object target = call.getTarget();
            Method method = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
            RequestData rd = AspectUtils.getRequestData(call, msig);
            //AspectUtils.findRequestBody(call, method, rd);
            //执行校验器
            ReturnData returnData = validate(call, method, rd);

            Object result = returnData;
            //无校验失败信息,则正常执行方法
            if (null == returnData) {

                result = call.proceed();

            }
            return result;
        } catch (Throwable e) {
            if (e instanceof BusinessException) {
                BusinessException ex = (BusinessException) e;
                throw ex;
            }
            if (e instanceof DecodeException) {
                return new ReturnData("-1", e.getMessage());
            }
            logger.error("内部错误", e);
            return new ReturnData("-1", "内部错误！");
        }
    }

    private ReturnData validate(ProceedingJoinPoint call, Method method, RequestData rd) {
        CityValidator cityValidator = method.getAnnotation(CityValidator.class);
        if (null != cityValidator) {
            String name = cityValidator.name();
            Long cityId = rd.getLong(name);
            List<City> cityList = cityClient.getCityList(cityId);
            if (CollectionUtils.isNotEmpty(cityList)) {
                for (City city : cityList) {
                    if (!Cons.COMMON_STATUS_ACTIVE.equals(city.getStatus())) {
                        return new ReturnData("-1", "当前城市未开通服务");
                    }
                }
            } else {
                return new ReturnData("-1", "当前城市未开通服务");
            }

        }
        return null;
    }


}
